#ifndef ACTOR_HPP
#define ACTOR_HPP

/*--------------------------------------------------------------------------------------------------------------
 * INCLUDES
 *-------------------------------------------------------------------------------------------------------------*/
#include "utils.hpp"
#include "Imagen.hpp"

namespace bp
{
	 
/*--------------------------------------------------------------------------------------------------------------
 * PUBLIC TYPES
 *-------------------------------------------------------------------------------------------------------------*/

typedef struct									
{
	int32_t							x_accion;		// Valor que aplicado a la coordenada X(Horizontalidad) mofica la posicion donde debe dibujarse el fotograma del movimiento
	int32_t							y_accion;		// Valor que aplicado a la coordenada Y(Verticalidad) mofica la posicion donde debe dibujarse el fotograma del movimiento

}												ty_s_guia_mov;
typedef struct									
{
	SDL_Surface*					imagen;  	// Imagen Jpeg, Gif fisica con todos los sprites de un perfil(Puntero a m_imagen<std::map<int32_t, SDL_Surface*>)
	int32_t							fuerza;  	// Potencia del movimeinto si es un golpe
	size_t							numero;		// Numero de fotogramas que componen el movimiento
	int32_t							retardo;	// Tiempo de lapso entre los fotogramas
	std::vector<ty_s_guia_mov>		guia;		// Valores que sumados a las cooredenadas cambian la direccion del movimiento
	std::vector<SDL_Rect>			sec_img;	// Coordenedas de cada fotograma en la ty_s_conf_mov.imagen	
	std::vector<Mix_Chunk*>			sec_fx;		// Efecto de sonido asocioado a cada fotograma
			
}												ty_s_conf_mov;
typedef struct									
{
	SDL_Rect						pos_actual;								// Coordenedas de la posicion actual
	SDL_Rect						pos_futura;								// Simulacion de donde quedan las futuras coordenadas del siguiente movimiento	
	int32_t							en_curso;								// Golpe, Avance, Patada...			
	int32_t							sentido;								// Izq-Der o Der-Izq
	size_t							ulti_sec;								// Si un movimiento tiene 4 fotogramas, el ultimo dibujado
	bool							repeticion[TipoMov_LEN - 1];			// Indica si un movimiento se usa de forma repetida sin soltar el boton que lo acciona
	int32_t							vida;									// Cantidad de vida o energia que tiene el actor
	
}												ty_s_status_mov;

typedef std::pair<int32_t, int32_t> 				ty_p_clave_mov; 	// <Tipo Movimeinto(golpe, avance, retroceso..), Sentido del movimeinto(Perfil derecho o izquierdo)>
typedef std::map<ty_p_clave_mov, ty_s_conf_mov> ty_m_conf_mov;		// <Clave del Movimiento, Datos de conf del movimiento>	



/*--------------------------------------------------------------------------------------------------------------
 * CLASS : ACTOR
 *-------------------------------------------------------------------------------------------------------------*/
class actor
{

	/*--------------------------------------------------------------------------------------------------------------
	* PRIVATE ATTRIBUTES
	*--------------------------------------------------------------------------------------------------------------*/
	private:			
		std::map<int32_t, SDL_Surface*>							m_imagen;
		const char*												m_nombre;				
		ty_m_conf_mov											m_mov_conf;
		ty_s_status_mov											m_mov_stat;						
		Keys_t													m_keys[SDLMAXKEYS];	

	/*--------------------------------------------------------------------------------------------------------------
	* PROTECTED ATTRIBUTES
	*--------------------------------------------------------------------------------------------------------------*/
	protected:
		int32_t													m_delay;

	/*--------------------------------------------------------------------------------------------------------------
	* PUBLIC ATTRIBUTES
	*--------------------------------------------------------------------------------------------------------------*/
	public:								
									actor						(const char* nombre, int32_t perfil, SDL_Rect PosInicial, int32_t vida = 100);
		virtual						~actor						(void);
		
		virtual void				CargarMovimiento			(ty_p_clave_mov clave_movimiento, ty_s_conf_mov movimiento) { m_mov_conf[clave_movimiento] = movimiento; }
		virtual bool				CargarImagenes				(const char* RutaImagenPerfilDer, const char* RutaImagenPerfilIzq);
		
		virtual bool				GestorMov					() { return true; }
		virtual bool				GestorMovAI					() { return true; }
		virtual void				EscanerColisiones			() {}		
		virtual void				ActivaTipoMovimiento		(int32_t tipo_movimiento, int32_t sentido);
		virtual void				DesActivaTipoMovimiento		();
		virtual void				InitMovs					();
		virtual void				ActivaDescanso				(int32_t tipo_movimiento = descanso, int32_t sentido = perfilDer) { ActivaTipoMovimiento(tipo_movimiento, sentido); }
		virtual void				SimulaMovimiento			(int32_t mov_x, int32_t mov_y, int32_t src_w, int32_t src_h);
		virtual void				ConsolidaMovimiento			();
				
		virtual void				Dibujar						(SDL_Surface*, int32_t ) {}
		
		
		// SETTER y GETER
		virtual SDL_Surface*&		imagen						(int32_t sentido) { return m_imagen[sentido]; }	
		virtual const char*			nombre						() { return m_nombre; }
		virtual ty_s_conf_mov*		mov_conf					(ty_p_clave_mov clave_mov) { return &m_mov_conf[clave_mov]; }	
		virtual	ty_s_status_mov*	mov_stat					() { return &m_mov_stat; }
		virtual	Keys_t*				teclas						(int32_t index) { return &m_keys[index]; }
		virtual	Keys_t*				teclas						(SDLKey index) { return &m_keys[index]; }				
		virtual void				resetTeclas					() { memset(m_keys, 0, sizeof(Keys_t) * SDLMAXKEYS); }
		virtual void				resetRepetTeclas			() { memset(m_mov_stat.repeticion, 0, sizeof(bool) * (TipoMov_LEN - 1)); }
		virtual void				SetDelay					(int32_t delay) { m_delay = delay; } 
		virtual int32_t				GetDelay					() { return m_delay; }
			
};

}
#endif //ACTOR
